#include "bsp_uart.h"
#include "at32f403a_407.h"

#include "cbb_init.h"

typedef struct bsp_uart_handle{
    uint8_t *pu8RxData;     // 接收缓存指针
    uint32_t u32MaxLen;     // 接收缓存最大长度
    uint32_t u32RxIndex;      // 接收缓存长度
    uint32_t u32Finished;    // 接收完成标志位
}bsp_uart_handle_t;

// 定义串口1的句柄
bsp_uart_handle_t bsp_uart1 = {0};

// 串口1中断函数
void USART1_IRQHandler(void){

    if(USART1->sts_bit.rdbf){

        // 清空接收完成标志
        bsp_uart1.u32Finished = 0;

        // 接收数据
        bsp_uart1.pu8RxData[bsp_uart1.u32RxIndex++] = USART1->dt;

        // 循环接收缓存
        if(bsp_uart1.u32RxIndex == bsp_uart1.u32MaxLen) bsp_uart1.u32RxIndex = 0;
    }

    if(USART1->sts_bit.idlef){

        // 清空标志
        USART1->sts;
        USART1->dt;

        // 接收完成标志
        bsp_uart1.u32Finished = 1;
    }
}

// 初始化串口1
void uart1_init(void){

    // 时钟
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
   
    // tx
    gpio_init_type GPIO_InitStructure;
    GPIO_InitStructure.gpio_pins = GPIO_PINS_9;
    GPIO_InitStructure.gpio_mode = GPIO_MODE_MUX;
    GPIO_InitStructure.gpio_pull = GPIO_PULL_NONE;
    GPIO_InitStructure.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    GPIO_InitStructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
    gpio_init(GPIOA, &GPIO_InitStructure);

    // rx
    GPIO_InitStructure.gpio_pins = GPIO_PINS_10;
    GPIO_InitStructure.gpio_mode = GPIO_MODE_INPUT;
    GPIO_InitStructure.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &GPIO_InitStructure);

    // USART1
    usart_init(USART1, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);
    usart_parity_selection_config(USART1, USART_PARITY_NONE);
    usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE);
    
    // 使能发送，接收
    usart_transmitter_enable(USART1, TRUE);
    usart_receiver_enable(USART1, TRUE);

    // 设置中断优先级
    nvic_irq_enable(USART1_IRQn, 0, 0);

    // 使能中断
    nvic_irq_enable(USART1_IRQn, 5, 0);

    // 接收中断
    usart_interrupt_enable(USART1, USART_IDLE_INT, TRUE);
    
    // 空闲中断
    usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE);

    // 开启串口
    usart_enable(USART1, TRUE);

}
INIT_PORT_BSP(uart1_init);

uint8_t uart1_transmit(uint8_t* pu8Data, uint32_t u32Len){

    for(uint32_t i = 0; i < u32Len; i++){

        // 发送数据
        usart_data_transmit(USART1, pu8Data[i]);
        
        // 阻塞式等待发送完成
        while(USART1->sts_bit.tdbe == RESET);
    }
    return 0;
}

uint32_t uart1_receive(uint8_t* pu8Data, uint32_t u32Len){

    // 设置缓存地址和大小 -- 仿照dma接收函数
    if(!bsp_uart1.pu8RxData){
        bsp_uart1.pu8RxData = pu8Data;
        bsp_uart1.u32MaxLen = u32Len;
    }

    // 获取接收完成标志位
    if(!bsp_uart1.u32Finished) return 0;
    bsp_uart1.u32Finished = 0;

    // 返回剩余的长度 -- 仿照dma接收函数
    return bsp_uart1.u32MaxLen - bsp_uart1.u32RxIndex;
}

// debug使用的打印函数
uint8_t uart1_printf(uint8_t u8Data){
    usart_data_transmit(USART1, u8Data);
    while(USART1->sts_bit.tdbe == RESET);
    return 0;
}

int __io_putchar(int ch){
    uart1_printf((uint8_t)ch);
    return ch;
}
